﻿using System;
using System.Collections.Generic;
using UnityEngine;
using GameProtocols;
using Framework;

public class VisualEntity : MonoBehaviour
{
    public int entityID { private set; get; }
    public long playerID { private set; get; }

    public int characterID { private set; get; }

    public ObjHandle<VisualEntity> self = ObjHandle<VisualEntity>.NULL;
    public bool isMainVisualEntity
    {
        get
        {
            return playerID == PlayerManager.Instance.MyPlayerID;
        }
    }
    List<VisualComponent> components = new List<VisualComponent>();
    public Action<Collider> onTriggerEnterDelegate;

    public static ObjHandle<VisualEntity> InitVisualEntitiy(int characterID, int entityID, long playerID)
    {
        string prefabPath = string.Format("Prefab/roles/{0}_mx", characterID);
        GameObject go = SimplePool.Spawn(prefabPath, Vector3.zero, Quaternion.identity);

        VisualEntity vEntity = go.GetComponent<VisualEntity>();
        ObjHandle<VisualEntity> handle = new ObjHandle<VisualEntity>(vEntity);
        vEntity.enabled = true;
        vEntity.characterID = characterID;
        vEntity.entityID = entityID;
        vEntity.playerID = playerID;
        vEntity.name = " EntityID: " + entityID + " PlayerID: " + playerID;
        vEntity.self = handle;
        for (int i = 0; i < vEntity.components.Count; i++)
        {
            vEntity.components[i].Init(vEntity);
        }
        for (int i = 0; i < vEntity.components.Count; i++)
        {
            vEntity.components[i].Start();
        }
        return handle;
    }

    public virtual void Destroy()
    {
        for (int i = 0; i < components.Count; i++)
        {
            components[i].OnDestroy();
        }
    }

    public T GetVisualComponent<T>() where T : class
    {
        for (int i = 0; i < components.Count; i++)
        {
            if (components[i] is T)
                return (T)components[i];
        }

        return null;
    }

    public void AddVisualComponent(VisualComponent component)
    {
        components.Add(component);
    }

    void Update()
    {
        for (int i = 0; i < components.Count; i++)
        {
            components[i].DoUpdate(Time.deltaTime);
        }
    }

    private void FixedUpdate()
    {
        for (int i = 0; i < components.Count; i++)
        {
            components[i].DoFixedUpdate(Config.FixedUpdateInterval);
        }
    }

    #region network

    private Dictionary<int, Action<object[]>> _msgDispatch = new Dictionary<int, Action<object[]>>();

    public void RegistMsg(int f_id, Action<object[]> f_func)
    {
        if (_msgDispatch.ContainsKey(f_id))
            _msgDispatch[f_id] += f_func;
        else
            _msgDispatch.Add(f_id, f_func);
    }

    public void UnregistMsg(int f_id, Action<object[]> f_func)
    {
        if (_msgDispatch.ContainsKey(f_id))
        {
            if (f_func == null)
            {
                _msgDispatch.Remove(f_id);
            }
            else
            {
                _msgDispatch[f_id] -= f_func;
            }
        }
        else
            Debug.LogWarning("Unregist unknow Message : " + f_id.ToString());
    }

    public void DispatchMsg(int msgID, object[] msg)
    {
        if (_msgDispatch.ContainsKey(msgID))
        {
            Action<object[]> fn = _msgDispatch[msgID];
            fn(msg);
        }
    }
    #endregion
}
